home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / parser / range_fcn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-02-08  |  9.8 KB  |  546 lines

  1. # include    <ingres.h>
  2. # include    <aux.h>
  3. # include    <tree.h>
  4. # include    <symbol.h>
  5. # include    <range.h>
  6. # include    "parser.h"
  7. # include    <sccs.h>
  8. # include    <errors.h>
  9.  
  10. SCCSID(@(#)range_fcn.c    8.3    2/8/85)
  11.  
  12. /*
  13. **    Range table variables
  14. */
  15.  
  16. PARRNG            Parrng[MAXRANGE]; /* table for keeping track of atts */
  17.                       /* and allocation of range vars */
  18. int            Resrng;        /* result reln slot */
  19.  
  20. PARRNG            *Rngfront;    /* the front of Rnga */
  21. PARRNG            *Rngback;    /* the back of Qt.qt_rangev */
  22.  
  23.  
  24. /*
  25. **  RANGE_FCN.C -- functions for manipulating the range table
  26. **
  27. **    Trace Flags:
  28. **        RANGE_FCN.C ~~ 66, 67
  29. */
  30.  
  31. ctlmod_decl(slot)
  32. int    slot;
  33. {
  34.     extern PARRNG    Parrng[];
  35.  
  36.     Qt.qt_rangev[slot].rngvdesc = NULL;
  37.     if (declare(slot, &Parrng[slot].vardesc) != slot)
  38.         syserr("declare misdeclared");
  39. }
  40.  
  41. /*
  42. **  RNGINIT
  43. **    initializes the pointers in the range table
  44. **    it should be called prior to starting the parsing
  45. **    it also initializes the attrib stash stuff because
  46. **    the attrib stash is really part of the range table
  47. **
  48. **    Trace Flags:
  49. **        rnginit ~~ 66.0
  50. */
  51. rnginit()
  52. {
  53.     register int        slot;
  54.     register PARRNG        *parrngptr;
  55.     register RANGEV        *rngptr;
  56.  
  57. #    ifdef    xPTR2
  58.     tTfp(66, 0, "rnginit\n");
  59. #    endif
  60.  
  61.     Rngfront = &Parrng[MAXVAR - 1];            /* ptr to head of range table */
  62.     parrngptr = Parrng;
  63.     /* initialize first element */
  64.     parrngptr->attlist = NULL;
  65.     parrngptr->backpt = NULL;
  66.     parrngptr->frontpt = &Parrng[1];
  67.  
  68.     rngptr = Qt.qt_rangev;
  69.  
  70.     for (slot = 0, parrngptr = &Parrng[1]; slot < MAXVAR; slot++, parrngptr++)
  71.     {
  72.         parrngptr->attlist = NULL;
  73.  
  74.         parrngptr->frontpt = parrngptr + 1;
  75.         parrngptr->backpt = parrngptr - 1;
  76.     }
  77.  
  78.     Rngback = Parrng;
  79.  
  80.     parrngptr = &Parrng[MAXVAR - 1];
  81.  
  82.     parrngptr->frontpt = NULL;
  83.  
  84.     /* MAXVAR SLOT = Resultvar */
  85.     (++parrngptr)->attlist = NULL;
  86.     parrngptr->frontpt = parrngptr->backpt = NULL;
  87.  
  88.     Rngfront->frontpt = NULL;
  89.  
  90.     clrrange();
  91.  
  92.     attinit();
  93. }
  94.  
  95. /*
  96. ** RNGLOOK
  97. **    returns a pointer to the range table entry else -1
  98. **    type = LOOKREL    lookup relation
  99. **    type = LOOKVAR    lookup variable
  100. **
  101. **    Trace Flags:
  102. **        rnglook ~~ 66.4, 66.5, 66.6
  103. */
  104. int
  105. rnglook(name, type)
  106. char        *name;
  107. int        type;
  108. {
  109.     register PARRNG        *rptr;
  110.  
  111.     register int        slot;
  112.  
  113.     DESC            reldesc;
  114.  
  115.     int            i;
  116.  
  117. #    ifdef    xPTR2
  118.     tTfp(66, 4, "rnglook:\ttype = %s\tname = %s\n",
  119.             (type == LOOKVAR ? "variable" : "relation"), name);
  120.  
  121.     if (tTf(66, 5))
  122.         printtable();
  123. #    endif
  124.  
  125.     rptr = Parrng;
  126.  
  127.     for (slot = 0; slot < MAXVAR; slot++, rptr++)    /* search external vbles only */
  128.     {
  129.         if (rptr->relvused
  130.             && scompare(name, MAXNAME,
  131.             (type == LOOKVAR ? rptr->vardesc.relvname : rptr->vardesc.reldum.relid),
  132.             MAXNAME) == 0)
  133.         {
  134.             Qt.qt_rangev[slot].rngvmark = 1;
  135.             
  136. #            ifdef    xPTR2
  137.             tTfp(66, 6, "fnd '%s' at '%d'\n", name, slot);
  138. #            endif
  139.  
  140.             rngfront(slot);
  141.             return (slot);
  142.         }
  143.     }
  144.  
  145.     /*
  146.     ** We haven't been able to find the variable, assume 
  147.     ** it is the name of a relation, and try and insert
  148.     ** a new range variable under that name.
  149.     */
  150.     if (type == LOOKVAR)
  151.     {
  152.         if ((i = openr(&reldesc, OR_RELTID, name)) < 0)
  153.             syserr("relname: error in openr '%d'", i);
  154.  
  155.         /*
  156.         ** rngent will call rnglook to create var if name
  157.         ** was a relation name
  158.         */
  159.         if (i == 0)
  160.             return(rngent(R_IMPLICIT, name, &reldesc));
  161.         else
  162.             return(-1);
  163.     }
  164.     return (-1);
  165. }
  166.  
  167. /*
  168. **  RNGENT
  169. **
  170. **    Insert variable and relation in range table.
  171. **
  172. **    Trace Flags:
  173. **         rngent ~~ 66.8
  174. */
  175.  
  176. int
  177. rngent(type, var, desc)
  178. int            type;
  179. char            *var;
  180. register DESC        *desc;
  181. {
  182.     register PARRNG    *rptr;
  183.     register int    slot;
  184.  
  185. #    ifdef    xPTR2
  186.     tTfp(66, 8, "rngent:\ttype=%s\tvar=%s\n",
  187.         (type == R_INTERNAL ? "internal" : "external"), var);
  188. #    endif
  189.  
  190.     if (type == R_INTERNAL)
  191.         slot = MAXVAR;        /* the internal variable */
  192.     else
  193.     {
  194.         if ((type == R_IMPLICIT) || (slot = rnglook(var, LOOKVAR)) < 0)
  195.         {
  196.             /* not in range table */
  197.             slot = rngold();
  198.         }
  199.  
  200.         rngfront(slot);
  201.     }
  202.  
  203.     rptr = &Parrng[slot];
  204.  
  205.     if (!bequal(desc, &rptr->vardesc, sizeof (*desc)))
  206.     {
  207.         attfree(rptr->attlist);
  208.         rptr->attlist = NULL;
  209.     }
  210.  
  211.     rptr->relvused = 1;
  212.  
  213.     bmove(desc, &rptr->vardesc, sizeof(*desc));
  214.     pmove(var, rptr->vardesc.relvname, MAXNAME, ' ');
  215.  
  216.     ctlmod_decl(slot);
  217.  
  218.     return (slot);
  219. }
  220.  
  221. /*
  222. ** RNGDEL
  223. **    removes an entry from the range table
  224. **    removes all variables for the relation name
  225. **
  226. **    Trace Flags:
  227. **         rngdel ~~ 66.12
  228. */
  229. rngdel(rel)
  230. register char    *rel;
  231. {
  232.     register int    slot;
  233.  
  234. # ifdef    xPTR2
  235.     tTfp(66, 12, "rngdel: %12s\n", rel);
  236. # endif
  237.  
  238.     while ((slot = rnglook(rel, LOOKREL)) >= 0)
  239.     {
  240.         Parrng[slot].relvused = 0;
  241.         rngback(slot);
  242.         attfree(Parrng[slot].attlist);
  243.         Parrng[slot].attlist = NULL;
  244.     }
  245. }
  246.  
  247.  
  248. /*
  249. ** RNGFRONT
  250. **    move entry 'r' to head of range table list
  251. **
  252. **    Trace Flags:
  253. **         rngfront ~~ 67.0 
  254. */
  255. rngfront(slot)
  256. int    slot;
  257. {
  258.     register PARRNG        *fptr;
  259.  
  260. #    ifdef    xPTR2
  261.     tTfp(67, 0, "rngfront:\tslot %d\n", slot);
  262. #    endif
  263.  
  264.  
  265.     rngget(slot);
  266.  
  267.     fptr = &Parrng[slot];
  268.  
  269.     fptr->frontpt = NULL;
  270.     fptr->backpt = Rngfront;
  271.     Rngfront->frontpt = fptr;
  272.  
  273.     Rngfront = fptr;
  274. }
  275.  
  276. /*
  277. ** RNGBACK
  278. **    move entry 'r' to back of range table list
  279. **
  280. **    Trace Flags:
  281. **        rngback ~~ 67.4
  282. */
  283. rngback(slot)
  284. int    slot;
  285. {
  286.     register PARRNG    *bptr;
  287.  
  288. #    ifdef    xPTR2
  289.     tTfp(67, 4, "rngback:\tslot %d\n", slot);
  290. #    endif
  291.  
  292.     rngget(slot);
  293.  
  294.     bptr = &Parrng[slot];
  295.  
  296.     bptr->backpt = NULL;
  297.     bptr->frontpt = Rngback;
  298.     Rngback->backpt = bptr;
  299.  
  300.     Rngback = bptr;
  301. }
  302.  
  303. /*
  304. **  RNGGET -- get a descriptor from range table
  305. **
  306. **    Trace Flags:
  307. **        rngget ~~ 67.8
  308. */
  309.  
  310. rngget(slot)
  311. int    slot;
  312. {
  313.     register PARRNG    *slotptr;
  314.     register PARRNG    *forward;
  315.     register PARRNG    *backward;
  316.  
  317. #    ifdef    xPTR2
  318.     tTfp(67, 8, "rngget:\tslot %d\n", slot);
  319. #    endif
  320.  
  321.  
  322.     slotptr = &Parrng[slot];
  323.     forward = slotptr->frontpt;
  324.     backward = slotptr->backpt;
  325.  
  326.     if (slotptr == Rngfront)
  327.     {
  328.         Rngfront = backward;
  329.         backward->frontpt = NULL;
  330.     }
  331.     else if (slotptr == Rngback)
  332.     {
  333.         Rngback = forward;
  334.         forward->backpt = NULL;
  335.     }
  336.     else
  337.     {
  338.         forward->backpt = backward;
  339.         backward->frontpt = forward;
  340.     }
  341.  
  342.     slotptr->backpt = slotptr->frontpt = NULL;
  343. }
  344.  
  345. /*
  346. **  RNGOLD -- find least recently used vble entry
  347. **
  348. **    Trace Flags:
  349. **        rngold ~~ 67.9
  350. */
  351. int
  352. rngold()
  353. {
  354. # ifdef    xPTR2
  355.     tTfp(67, 9, "rngold %d.\n", Rngback - (PARRNG *) Parrng);
  356. # endif
  357.  
  358.     return(Rngback - (PARRNG *) Parrng);
  359. }
  360.  
  361. /*
  362. ** RNGRESET
  363. **    reset the used marks to '0'
  364. **
  365. **    Trace Flags:
  366. **        rngreset ~~ 67.10
  367. */
  368. rngreset()
  369. {
  370.     register int        i;
  371.     register RANGEV        *rangevptr;
  372.  
  373. # ifdef    xPTR2
  374.     tTfp(67, 10, "rngreset().\n");
  375. # endif
  376.  
  377.     rangevptr = Qt.qt_rangev;
  378.  
  379.     for (i = 0; i < MAXVAR; i++, rangevptr++) /* only do external ones */
  380.         rangevptr->rngvmark = 0;
  381. }
  382.  
  383. /*
  384. ** CHECKUPD
  385. **    checks to make sure that the user can update the relation 'name1'
  386. **    the 'open' parameter is set if 'Reldesc' contains the openr info
  387. **    for the relation in question.
  388. **
  389. **    Trace Flags:
  390. **        checkupd ~~ 67.11
  391. */
  392. checkupd(entnum)
  393. int    entnum;
  394. {
  395.     extern int        Noupdt;
  396.     extern PARRNG        Parrng[];
  397.     register PARRNG        *rptr;
  398.  
  399. # ifdef    xPTR2
  400.     tTfp(67, 11, "checkupd(%d).\n", entnum);
  401. # endif
  402.  
  403.     rptr = &Parrng[entnum];
  404.  
  405.     if (!Noupdt)
  406.         return;
  407.     if (rptr->vardesc.reldum.relstat & S_NOUPDT)
  408.         /* no updates allowed on this relation */
  409.         par_error(CANTUPDATE, WARN, trim_relname(rptr->vardesc.reldum.relid), 0);
  410. }
  411.  
  412. /*
  413. ** RNGFRESH -- check the range table relstat information for accuracy
  414. **
  415. **    If the command specified could have changed the relstat info
  416. **    make the appropriate adjustments to the range table
  417. */
  418. rngfresh(op)
  419. int    op;
  420. {
  421.     register PARRNG        *rptr;
  422.     register int        slot;
  423.     DESC            desc;
  424.     char            var[MAXNAME];
  425.  
  426. # ifdef    xPTR2
  427.     tTfp(67, 11, "rngfresh %d.\n", op);
  428. # endif
  429.  
  430.     /* search the entire table! */
  431.     for (slot = 0, rptr = Parrng; slot <= MAXVAR; slot++, rptr++)
  432.     {
  433.         if (!(rptr->relvused))
  434.             continue;
  435.  
  436.         switch (op)
  437.         {
  438.           case mdDESTROY:
  439.             if ((rptr->vardesc.reldum.relstat & (S_VBASE | S_INTEG | S_PROTUPS | S_INDEX)) != 0)
  440.             {
  441.             fixordel:
  442.                 /*
  443.                 ** openr the relation, if it doesn't exist make
  444.                 ** sure that all range table entries are gone
  445.                 */
  446.                 if (!openr(&desc, OR_RELTID, rptr->vardesc.reldum.relid))
  447.                     rptr->vardesc.reldum.relstat = desc.reldum.relstat;
  448.                 else
  449.                     /* relation not there, purge table */
  450.                     rngdel(rptr->vardesc.reldum.relid);
  451.             }
  452.             break;
  453.  
  454.           case mdVIEW:
  455.             if ((rptr->vardesc.reldum.relstat & S_VBASE) == 0)
  456.             {
  457.             fixorerr:
  458.                 /*
  459.                 ** if the relation doesn't exist then it is
  460.                 ** a syserr, otherwise, copy the bits.
  461.                 */
  462.                 if (!openr(&desc, OR_RELTID, rptr->vardesc.reldum.relid))
  463.                     rptr->vardesc.reldum.relstat = desc.reldum.relstat;
  464.                 else
  465.                 {
  466.                     /* not there, syserr */
  467.                     syserr("RNGFRESH: extra entry: %s", rptr->vardesc.reldum.relid);
  468.                 }
  469.             }
  470.             break;
  471.  
  472.           case mdPROT:
  473.             if ((rptr->vardesc.reldum.relstat & S_PROTUPS) == 0)
  474.                 goto    fixorerr;
  475.             break;
  476.  
  477.           case mdINTEG:
  478.             if ((rptr->vardesc.reldum.relstat & S_INTEG) == 0)
  479.                 goto    fixorerr;
  480.             break;
  481.  
  482.           case mdMODIFY:
  483.             if (!openr(&desc, OR_RELTID, rptr->vardesc.reldum.relid))
  484.                 if (!bequal(&rptr->vardesc, &desc, sizeof desc))
  485.                 /* relation structure may have changed, adjust range variable */
  486.                 {
  487.                     bmove(rptr->vardesc.relvname, var, MAXNAME);
  488.                     rngent(R_EXTERNAL, var, &desc);
  489.                 }
  490.             if ((rptr->vardesc.reldum.relstat & S_INDEX) != 0)
  491.                 goto    fixordel;
  492.             break;
  493.         
  494.           default:
  495.             return;    /* command ok, dont waste time on rest of table */
  496.         }
  497.     }
  498. }
  499.  
  500. printtable()
  501. {
  502.     register PARRNG        *rptr;
  503.     int            slot[MAXRANGE];
  504.     int            i;
  505.  
  506.     printf("Range table:\n");
  507.  
  508.     for (i = 0; i < MAXRANGE; i++)
  509.         slot[i] = 0;
  510.  
  511.     for (rptr = Rngfront; rptr != NULL; rptr = rptr->backpt)
  512.     {
  513.         i = rptr - (PARRNG *) Parrng;
  514.         slot[i] = 1;
  515.         printslot(i);
  516.     }
  517.     printf("\nEntries not in list:\n");
  518.     for (i = 0; i < MAXRANGE; i++)
  519.     {
  520.         if (!slot[i])
  521.         {
  522.             printslot(i);
  523.         }
  524.     }
  525. }
  526.  
  527. printslot(slot)
  528. int    slot;
  529. {
  530.     register RANGEV        *rptr;
  531.     register PARRNG        *auxptr;
  532.  
  533.     rptr = &Qt.qt_rangev[slot];
  534.     auxptr = &Parrng[slot];
  535.  
  536.     printf("slot:\t%d\n{\trvar:\t%.12s,\trelnm:\t%.12s.\n",
  537.         slot, auxptr->vardesc.relvname,
  538.         auxptr->vardesc.reldum.relid);
  539.     printf("\tRELVUSED: %d, RELVSEND %d.\n",
  540.         auxptr->relvused,
  541.         rptr->rngvmark);
  542.  
  543.  
  544.     printf("\tratts: %d, attlist: %d.\n}\n", auxptr->vardesc.reldum.relatts, auxptr->attlist);
  545. }
  546.